﻿using System;
using System.Windows.Forms;

namespace LogicProtocolAnalyzer
{
    public partial class SettingsForm : Form
    {
        internal Settings Settings { get; set; }

        public SettingsForm()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            InitSettingForm();

            base.OnLoad(e);
        }

        private void InitSettingForm()
        {
            triggerLevelChannel0.Channel = 0;
            triggerLevelChannel1.Channel = 1;
            triggerLevelChannel2.Channel = 2;
            triggerLevelChannel3.Channel = 3;
            triggerLevelChannel4.Channel = 4;
            triggerLevelChannel5.Channel = 5;
            triggerLevelChannel6.Channel = 6;
            triggerLevelChannel7.Channel = 7;

            // Fill sample frequencies combo box
            Array freqValues = Enum.GetValues(typeof(SampleFrequency));
            Array.Sort(freqValues);
            comboBoxFrequency.Items.Clear();
            foreach (SampleFrequency sampleFrequency in freqValues)
            {
                if (sampleFrequency.AsString() != ExtensionMethods.Unknown)
                {
                    comboBoxFrequency.Items.Add(sampleFrequency.AsString());
                }
            }

            // Fill buffer size combo box
            // Buffer sizes range from 1024 (2 pow 10) to 32768 (2 pow 15)
            comboBoxBufferSize.Items.Clear();
            for (int i = 10; i <= 15; i++)
            {
                comboBoxBufferSize.Items.Add(Math.Pow(2, i).ToString());
            }

            // Fill the channel compare radio buttons
            triggerLevelChannel0.Level = this.Settings.GetAutoCompareTriggerLevel(0);
            triggerLevelChannel1.Level = this.Settings.GetAutoCompareTriggerLevel(1);
            triggerLevelChannel2.Level = this.Settings.GetAutoCompareTriggerLevel(2);
            triggerLevelChannel3.Level = this.Settings.GetAutoCompareTriggerLevel(3);
            triggerLevelChannel4.Level = this.Settings.GetAutoCompareTriggerLevel(4);
            triggerLevelChannel5.Level = this.Settings.GetAutoCompareTriggerLevel(5);
            triggerLevelChannel6.Level = this.Settings.GetAutoCompareTriggerLevel(6);
            triggerLevelChannel7.Level = this.Settings.GetAutoCompareTriggerLevel(7);

            // Fill the channel combo box
            comboBoxChannelEdgeNumber.Items.Clear();
            for (int index = 0; index < AnalyzerControl.NumberOfChannels; index++)
            {
                comboBoxChannelEdgeNumber.Items.Add((index + 1).ToString());
            }

            // Fill COM-port combo box
            comboBoxComPort.Items.Clear();
            if (this.Settings.PortNames.Length == 0)
            {
                comboBoxComPort.SelectedText = "No COM-ports available";
                comboBoxComPort.Enabled = false;
            }
            else
            {
                comboBoxComPort.Items.AddRange(this.Settings.PortNames);

                // Restore the combo box indexes
                // No COM-port previously selected
                if (this.Settings.PortName == string.Empty)
                {
                    // Select the first
                    comboBoxComPort.SelectedIndex = 0;
                }
                else
                {
                    bool portFound = false;
                    foreach (string portName in comboBoxComPort.Items)
                    {
                        if (portName == this.Settings.PortName)
                        {
                            comboBoxComPort.SelectedItem = portName;
                            portFound = true;
                            continue;
                        }
                    }
                    if (portFound == false)
                    {
                        MessageBox.Show(string.Format("COM-port '{0}' not found; '{1}' selected.", this.Settings.PortName, this.Settings.PortNames[0]), MainForm.Title);
                        comboBoxComPort.SelectedIndex = 0;
                    }
                }
            }
            comboBoxFrequency.SelectedIndex = (int)this.Settings.SampleFrequency;
            comboBoxBufferSize.SelectedIndex = this.Settings.SampleSize;
            comboBoxChannelEdgeNumber.SelectedIndex = this.Settings.AutoEdgeChannelIndex;

            switch (this.Settings.AutoEdgeDirection)
            {
                case TriggerEdge.Rising:
                    radioButtonRising.Checked = true;
                    break;
                case TriggerEdge.Falling:
                    radioButtonFalling.Checked = true;
                    break;
            }

            switch (this.Settings.TriggerMode)
            {
                case TriggerMode.AutoCmp:
                    radioButtonAutoCmp.Checked = true;
                    break;
                case TriggerMode.AutoEdge:
                    radioButtonAutoEdge.Checked = true;
                    break;
                case TriggerMode.Manual:
                    radioButtonManual.Checked = true;
                    break;
            }
            EnableTriggerGroupBox();
        }

        private TriggerMode TriggerMode
        {
            get
            {
                if (radioButtonAutoCmp.Checked)
                {
                    return TriggerMode.AutoCmp;
                }
                else if (radioButtonAutoEdge.Checked)
                {
                    return TriggerMode.AutoEdge;
                }
                else
                {
                    return TriggerMode.Manual;
                }
            }
        }

        private void SaveSettings()
        {
            this.Settings.SampleFrequency = (SampleFrequency)comboBoxFrequency.SelectedIndex;
            this.Settings.PortName = (string)comboBoxComPort.SelectedItem;
            this.Settings.SampleSize = comboBoxBufferSize.SelectedIndex;
            this.Settings.TriggerMode = TriggerMode;
            this.Settings.AutoEdgeChannelIndex = comboBoxChannelEdgeNumber.SelectedIndex;
            this.Settings.AutoEdgeDirection = radioButtonFalling.Checked ? TriggerEdge.Falling : TriggerEdge.Rising;
            this.Settings.SetAutoCompareTriggerLevel(0, triggerLevelChannel0.Level);
            this.Settings.SetAutoCompareTriggerLevel(1, triggerLevelChannel1.Level);
            this.Settings.SetAutoCompareTriggerLevel(2, triggerLevelChannel2.Level);
            this.Settings.SetAutoCompareTriggerLevel(3, triggerLevelChannel3.Level);
            this.Settings.SetAutoCompareTriggerLevel(4, triggerLevelChannel4.Level);
            this.Settings.SetAutoCompareTriggerLevel(5, triggerLevelChannel5.Level);
            this.Settings.SetAutoCompareTriggerLevel(6, triggerLevelChannel6.Level);
            this.Settings.SetAutoCompareTriggerLevel(7, triggerLevelChannel7.Level);

            this.Settings.Save();
        }

        private void EnableTriggerGroupBox()
        {
            if (radioButtonAutoCmp.Checked)
            {
                groupBoxAutoCmp.Enabled = true;
                groupBoxAutoEdge.Enabled = false;
            }
            else if (radioButtonAutoEdge.Checked)
            {
                groupBoxAutoCmp.Enabled = false;
                groupBoxAutoEdge.Enabled = true;
            }
            else //if(radioButtonManual.Checked)
            {
                groupBoxAutoCmp.Enabled = false;
                groupBoxAutoEdge.Enabled = false;
            }
        }

        private void radioButtonTrigger_CheckedChanged(object sender, EventArgs e)
        {
            EnableTriggerGroupBox();
        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            SaveSettings();

            Close();
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            InitSettingForm();

            e.Cancel = true;

            Hide();
        }

        private void buttonApply_Click(object sender, EventArgs e)
        {
            SaveSettings();
        }
    }
}
